package com.kunpeng.weibo.tencent.utils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import java.util.zip.GZIPInputStream;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;

import com.kunpeng.weibo.sina.beans.WeiboParameters;
import com.kunpeng.weibo.sina.http.HttpTask.MySSLSocketFactory;

public class QHttpClient {

	public static final String	BOUNDARY				= "7cd4a6d158c";
	public static final String	MP_BOUNDARY				= "--" + BOUNDARY;
	public static final String	END_MP_BOUNDARY			= "--" + BOUNDARY + "--";
	public static final String	MULTIPART_FORM_DATA		= "multipart/form-data";

	public static final String	HTTPMETHOD_POST			= "POST";
	public static final String	HTTPMETHOD_GET			= "GET";
	public static final String	HTTPMETHOD_DELETE		= "DELETE";

	private static final int	SET_CONNECTION_TIMEOUT	= 50000;
	private static final int	SET_SOCKET_TIMEOUT		= 200000;

	public QHttpClient() {

	}

	/**
	 * Using GET method.
	 * 
	 * @param url The remote URL.
	 * @param queryString The query string containing parameters
	 * @return Response string.
	 * @throws Exception
	 */
	public String httpGet(String url, String queryString) throws Exception {
		String responseData = null;

		if (queryString != null && !queryString.equals("")) {
			url += "?" + queryString;
		}

		org.apache.http.client.HttpClient httpClient = Utils.getNewHttpClient();
		HttpGet get = new HttpGet(url);
		get.getParams().setParameter("http.socket.timeout", new Integer(SET_CONNECTION_TIMEOUT));
		try {
			HttpResponse response = httpClient.execute(get);

			StatusLine status = response.getStatusLine();
			int statusCode = status.getStatusCode();

			if (statusCode != 200) {
				throw new Exception(String.format(status.toString()));
			}
			responseData = read(response);
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			httpClient = null;
		}
		return responseData;
	}

	/**
	 * Read http requests result from response .
	 * 
	 * @param response : http response by executing httpclient
	 * 
	 * @return String : http response content
	 */
	private static String read(HttpResponse response) throws Exception {
		String result = "";
		HttpEntity entity = response.getEntity();
		InputStream inputStream;
		try {
			inputStream = entity.getContent();
			ByteArrayOutputStream content = new ByteArrayOutputStream();

			Header header = response.getFirstHeader("Content-Encoding");
			if (header != null && header.getValue().toLowerCase().indexOf("gzip") > -1) {
				inputStream = new GZIPInputStream(inputStream);
			}

			// Read response into a buffered stream
			int readBytes = 0;
			byte[] sBuffer = new byte[512];
			while ((readBytes = inputStream.read(sBuffer)) != -1) {
				content.write(sBuffer, 0, readBytes);
			}
			// Return result from buffered stream
			result = new String(content.toByteArray());
			return result;
		} catch (IllegalStateException e) {
			throw e;
		} catch (IOException e) {
			throw e;
		}
	}

	/**
	 * Using POST method.
	 * 
	 * @param url The remote URL.
	 * @param queryString The query string containing parameters
	 * @return Response string.
	 * @throws Exception
	 */
	public String httpPost(String url, String queryString) {
		String responseData = null;
		try {
			HttpClient httpClient = getNewHttpClient();
			HttpPost httpPost = new HttpPost(url);
			httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
			if (queryString != null && !queryString.equals("")) {
				httpPost.setEntity(new ByteArrayEntity(queryString.getBytes()));
			}
			HttpResponse response = httpClient.execute(httpPost);
			StatusLine status = response.getStatusLine();
			int statusCode = status.getStatusCode();
			if (statusCode == HttpStatus.SC_OK) {
				responseData = read(response);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		//		HttpClient httpClient = new HttpClient();
		//		
		//		PostMethod httpPost = new PostMethod(url);
		//		httpPost.addParameter("Content-Type", "application/x-www-form-urlencoded");
		//		httpPost.getParams().setParameter("http.socket.timeout", new Integer(CONNECTION_TIMEOUT));
		//		if (queryString != null && !queryString.equals("")) {
		//			httpPost.setRequestEntity(new ByteArrayRequestEntity(queryString.getBytes()));
		//		}
		//
		//		try {
		//			int statusCode = httpClient.executeMethod(httpPost);
		//			if (statusCode != HttpStatus.SC_OK) {
		//				System.err.println("HttpPost Method failed: " + httpPost.getStatusLine());
		//			}
		//			responseData = httpPost.getResponseBodyAsString();
		//		} catch (Exception e) {
		//			throw new Exception(e);
		//		} finally {
		//			httpPost.releaseConnection();
		//			httpClient = null;
		//		}

		return responseData;
	}

	/**
	 * Using POST method with multiParts.
	 * 
	 * @param url The remote URL.
	 * @param queryString The query string containing parameters
	 * @param files The list of image files
	 * @return Response string.
	 * @throws Exception
	 */
	public String httpPostWithFile(String url, String queryString, String picPath) {

		String responseData = null;
		url += '?' + queryString;

		//		HttpUriRequest request = null;
		ByteArrayOutputStream bos = null;

		try {
			byte[] data = null;
			bos = new ByteArrayOutputStream(1024 * 50);

			HttpClient httpClient = getNewHttpClient();
			HttpPost httpPost = new HttpPost(url);
			httpPost.setHeader("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);
			Bitmap bf = BitmapFactory.decodeFile(picPath);
			imageContentToUpload(bos, bf);
			data = bos.toByteArray();
			bos.close();
			ByteArrayEntity formEntity = new ByteArrayEntity(data);
			httpPost.setEntity(formEntity);
			//			httpPost.setHeader("Authorization", queryString);
			HttpResponse response = httpClient.execute(httpPost);
			StatusLine status = response.getStatusLine();
			int statusCode = status.getStatusCode();

			if (statusCode == HttpStatus.SC_OK) {
				responseData = read(response);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		//		HttpClient httpClient = new HttpClient();
		//		PostMethod httpPost = new PostMethod(url);
		//		try {
		//			List<QParameter> listParams = QHttpUtil.getQueryParameters(queryString);
		//			int length = listParams.size() + (files == null ? 0 : files.size());
		//			Part[] parts = new Part[length];
		//			int i = 0;
		//			for (QParameter param : listParams) {
		//				parts[i++] = new StringPart(param.getName(), QHttpUtil.formParamDecode(param.getValue()), "UTF-8");
		//			}
		//
		//			for (QParameter param : files) {
		//				String filePath = param.getValue();
		//				File file = new File(filePath);
		//				String name = param.getName();
		//				//				String fileName = file.getName();
		//				//				String type = QHttpUtil.getContentType(file);
		//
		//				// image/jpeg - image/png
		//				parts[i++] = new FilePart(name, file, "image/jpeg", "utf-8");
		//			}
		//
		//			httpPost.setRequestEntity(new MultipartRequestEntity(parts, httpPost.getParams()));
		//
		//			int statusCode = httpClient.executeMethod(httpPost);
		//			if (statusCode != HttpStatus.SC_OK) {
		//				System.err.println("HttpPost Method failed: " + httpPost.getStatusLine());
		//			}
		//			responseData = httpPost.getResponseBodyAsString();
		//		} catch (Exception e) {
		//			throw new Exception(e);
		//		} finally {
		//			httpPost.releaseConnection();
		//			httpClient = null;
		//		}

		return responseData;
	}

	public HttpClient getNewHttpClient() throws Exception {
		KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
		trustStore.load(null, null);

		SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
		sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

		HttpParams params = new BasicHttpParams();

		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

		SchemeRegistry registry = new SchemeRegistry();
		registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
		registry.register(new Scheme("https", sf, 443));

		ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

		HttpConnectionParams.setConnectionTimeout(params, SET_CONNECTION_TIMEOUT);
		HttpConnectionParams.setSoTimeout(params, SET_SOCKET_TIMEOUT);
		HttpClient client = new DefaultHttpClient(ccm, params);
		return client;
	}

	/**
	 * Upload weibo contents into output stream .
	 * 
	 * @param baos : output stream for uploading weibo
	 * @param params : post parameters for uploading
	 * @return void
	 * @throws IOException
	 */
	private void paramToUpload(OutputStream baos, WeiboParameters params) throws IOException {
		String key = "";
		for (int loc = 0; loc < params.size(); loc++) {
			key = params.getKey(loc);
			StringBuilder temp = new StringBuilder(10);
			temp.setLength(0);
			temp.append(MP_BOUNDARY).append("\r\n");
			temp.append("content-disposition: form-data; name=\"").append(key).append("\"\r\n\r\n");
			temp.append(params.getValue(key)).append("\r\n");
			byte[] res = temp.toString().getBytes();
			baos.write(res);
		}
	}

	/**
	 * Upload image into output stream .
	 * 
	 * @param out : output stream for uploading weibo
	 * @param imgpath : bitmap for uploading
	 * @return void
	 * @throws IOException
	 */
	private void imageContentToUpload(OutputStream out, Bitmap imgpath) throws IOException {
		StringBuilder temp = new StringBuilder();

		temp.append(MP_BOUNDARY).append("\r\n");
		temp.append("Content-Disposition: form-data; name=\"pic\"; filename=\"").append("news_image").append("\"\r\n");
		String filetype = "image/png";
		temp.append("Content-Type: ").append(filetype).append("\r\n\r\n");
		byte[] res = temp.toString().getBytes();
		out.write(res);
		imgpath.compress(CompressFormat.PNG, 75, out);
		out.write("\r\n".getBytes());
		out.write(("\r\n" + END_MP_BOUNDARY).getBytes());
	}
}
